
#include <memory>
#include <functional>

#include "VoiceRecoEngine.h"
#include "VoiceRecoSession.h"
#include "Task.h"

#include "Utility/RefPtr.h"

using namespace std;
using namespace nebula::utility;

namespace smartvoice {

REGISTER_SERVICE("voice-engine", VoiceRecoEngine);

/////////////////////////////////////////////////////////////////////////////

VoiceRecoEngine::VoiceRecoEngine() :
	_task_queue(0),
	_sess_manager(new VoiceSessionManager)
{
}

NEBULA_ERROR_CODE VoiceRecoEngine::OnInitialize()
{
	NEBULA_ERROR_CODE rc = NEBULA_ERR_SUCCESS;

	RegisterPushSlot("data", &SessionTask::Allocator, &VoiceRecoEngine::VoiceTaskProc, 1, 20);
	RegisterPopSlot ("data", &_task_queue);

	//init QISR system
	if ((rc = _sess_manager->LoadConfig("conf/voicerecoengine.ini")) != NEBULA_ERR_SUCCESS)
		return rc;
	
	if ((rc = _sess_manager->InitEnv()) != NEBULA_ERR_SUCCESS)
		return rc;

	return NEBULA_ERR_SUCCESS;
}

NEBULA_ERROR_CODE VoiceRecoEngine::OnStart()
{
	return StartThreadPool();
}

void VoiceRecoEngine::OnStop()
{
	StopThreadPool();
}

void VoiceRecoEngine::OnFinalize()
{
}

const char* VoiceRecoEngine::MatchSessPara(ITask* ptask)
{
	return NEBULA_ERR_SUCCESS;

}

NEBULA_ERROR_CODE VoiceRecoEngine::VoiceTaskProc(std::auto_ptr<ITask> task)
{
	NEBULA_ERROR_CODE rc = NEBULA_ERR_SUCCESS;

	const char* templatename = MatchSessPara(task.get());
	if (templatename == 0)
		templatename = "default";
	
	ref_ptr<VoiceRecoSession> psession(
		_sess_manager->AllocSession(templatename),
		std::bind1st( std::mem_fun(&VoiceSessionManager::CloseSession), _sess_manager)
		);
	if ((rc = psession->CommitTask(task.get())) != NEBULA_ERR_SUCCESS)
	{
		perror("Submit task to VoiceCloud failed, return code = %d", rc);
		return rc;
	}

	//TODO: place voice format transfer process here

	if ((rc = _task_queue->AddTask(task.release())) != NEBULA_ERR_SUCCESS)
	{
		perror("Add task to done queue failed, return code = %d", rc);
		return rc;
	}

	return NEBULA_ERR_SUCCESS;
}

} // namespace smartvoice

